#include <iostream>
using namespace std;
//确定一下虚函数表在内存中的分布
//
class base{
    public:
    virtual
        void show(){
            cout<<"show1"<<endl;
        }
    virtual 
        void print(){
            cout<<"print"<<endl;
        }
    ~base(){
        cout<<"~base"<<endl;
    }
    size_t num=10;
};

class B: public base{
public:
    size_t num2=20;
    ~B(){
        cout<<"~B"<<endl;
    }
};
void test(){
   base ba;
   B b;
    //数据成员8字节，指向虚表的指针8字节
    cout<<sizeof(ba)<<endl;
    //指向虚表的指针8字节，字节的数据成员和父类的数据成员16字节
    cout<<sizeof(b)<<endl;
    //接下来查看在子类的内存空间里面，这两个数据是怎么分布的
    base * p=&b;
    size_t * pl=(size_t*)p;
    cout<<*pl<<endl;
    cout<<*(pl+1)<<endl;
    cout<<*(pl+2)<<endl;
    //分别是地址值，10,20
    //地址值是虚函数中存的函数指针
    //10，和20分别代表了父类和子类的变量成员
    
    //现在根据第一个地址值，来判断这个地址值是什么，有什么用
    //第一个值是一个指针，指向的是虚表，通过解引用操作，可以使得
    //指针指向虚表的第一个函数指针
    //现在的vtable就是一个指向虚表第一个元素的指针，而这个指针指向的是一个函数的指针
    //所以解引用这个指针，可以得到一个函数的指针，用一个函数指针类型的指针来接受
    //解引用后的vtable，那么函数指针类型的指针可以直接调用函数了
    long * vtable=(long*)*pl;

    typedef void(*pFunc)(void);
    pFunc pf1=(pFunc)*vtable;
    pFunc pf2=(pFunc)*(vtable+1);
    pf1();
    pf2();
}
    int main(int argc, char * argv[]){
    test();   
    return 0;
}

